package main

import (
	"context"
	"encoding/json"
	"fmt"
	"regexp"
	"strconv"
	"strings"
)

// 二进制数据的结构体
type sliceValue []string
type sliceInt []int64

//字符串转数组处理
func (s *sliceValue) Set(val string) error {
	*s = sliceValue(strings.Split(val, "|"))
	return nil
}

//flag为slice的默认值default is me,和return返回值没有关系
func (s *sliceValue) String() string {
	// *s = sliceValue(strings.Split("", "|"))
	return "none"
}

//字符转数组后转数字处理
func (s *sliceInt) Set(val string) error {
	str_ary := strings.Split(val, "|")
	int_ary, _ := Avg_strtoint(str_ary)
	*s = sliceInt(int_ary)
	return nil
}

//flag为slice的默认值default is me,和return返回值没有关系
func (s *sliceInt) String() string {
	// *s = sliceValue(strings.Split("", "|"))
	return "none"
}

// 二进制数据交互
type bytestore struct {
	storetype   string
	status      bool // 判断是否有一级
	read_status bool
	object      Basis
}

type mapstore map[string]bytestore

// 接口
type Basis interface {
	Init_judge() (bool, error)
	Start_str(indata chan *string, outdata chan *string)
	Logical_processing(s string) (string, bool)
}

// 普通匹配
type Parameter_is struct {
	in_related_string  sliceValue // 匹配的字符
	or_related_string  sliceValue //包含其中一个字符就记录
	out_related_string sliceValue // 排除的字符
	updown_type        string
	upward_list        []*string
	upward_num         int
	down_num           int
}

// 单字符匹配
type Parameter_ois struct {
	one_in_string string
}

// 截取功能
type Parameter_ss struct {
	split_symbol      string
	split_symbol_list []string
	split_location    sliceInt
	split_type        string
}

// 正则
type Parameter_zz struct {
	regular_grammar string
	regular_type    string
	regular_Regexp  *regexp.Regexp
}

//
type State_manage struct {
	ctx          context.Context
	cancel       context.CancelFunc
	error_status int
	error_txt    error
}

func (pis *Parameter_is) Init_judge() (bool, error) {
	if len(pis.in_related_string) > 0 || len(pis.out_related_string) > 0 || len(pis.or_related_string) > 0 {
		if pis.updown_type == "default" {
			return true, nil
		} else {
			pis.upward_list = []*string{}
			if len(pis.out_related_string) > 0 {
				return false, fmt.Errorf("范围打印仅允许普通匹配-a或-m")
			}
			switch pis.updown_type {
			case "all":
				if pis.upward_num > 0 && pis.down_num > 0 {
					return true, nil
				} else {
					return false, fmt.Errorf("必须指定上下打印范围")
				}
			case "up":
				if pis.upward_num > 0 {
					return true, nil
				} else {
					return false, fmt.Errorf("必须指定向上打印范围")
				}
			case "down":
				if pis.down_num > 0 {
					return true, nil
				} else {
					return false, fmt.Errorf("必须指定向下打印范围")
				}
			}
			return false, fmt.Errorf("没有匹配对应的范围打印模式")
		}
	} else {
		return false, nil
	}
}

func (ois *Parameter_ois) Init_judge() (bool, error) {
	if ois.one_in_string != "none" {
		return true, nil
	} else {
		return false, nil
	}
}

func (pss *Parameter_ss) Init_judge() (bool, error) {
	var err error
	var split_symbol_list []string
	if pss.split_type == "none" {
		if len(pss.split_location) == 0 && pss.split_symbol == "none" { // 没有配置的情况（全是默认值）
			return false, nil
		} else {
			return false, fmt.Errorf("必须配置截取模式!")
		}
	} else if pss.split_type == "jane" {
		if len(pss.split_location) > 0 && pss.split_symbol != "none" {
			split_symbol_list, err = symbol_mod(pss.split_symbol) // 判断分隔符是否存在异常并赋值
			pss.split_symbol_list = split_symbol_list
			if err != nil {
				return false, err
			}
			return true, nil
		} else {
			return false, fmt.Errorf("必须配置分隔符及指定位置!")
		}
	} else if pss.split_type == "sum" || pss.split_type == "num" || pss.split_type == "avg" {
		if len(pss.split_location) == 1 && pss.split_symbol != "none" {
			split_symbol_list, err = symbol_mod(pss.split_symbol) // 判断分隔符是否存在异常并赋值
			pss.split_symbol_list = split_symbol_list
			if err != nil {
				return false, err
			}
			return true, nil
		} else {
			return false, fmt.Errorf("必须配置分隔符及指定位置, 指定位置仅允许单个!")
		}
	} else {
		return false, fmt.Errorf("配置截取模式异常!\n")
	}
}

func (pis *Parameter_is) Start_str(in_data chan *string, outdata chan *string) {
	// defer func() {
	// 	if r := recover(); r != nil {
	// 		fmt.Println("Start_str error")
	// 	}
	// }()
	// 根据不同类型处理数据
	switch pis.updown_type {
	case "default":
		for {
			idata, isclosed := <-in_data
			if !isclosed {
				close(outdata)
				return
			}
			sdata := *idata
			if _, ok := pis.Logical_processing(sdata); ok {
				outdata <- idata
			}
		}
	case "up":
		for {
			idata, isclosed := <-in_data
			if !isclosed {
				close(outdata)
				return
			}
			sdata := *idata
			pis.Match_up(idata)
			if _, ok := pis.Logical_processing(sdata); ok {
				r_list := pis.Match_extract()
				for _, r := range r_list {
					outdata <- r
				}
			}
		}
	case "down":
		var down_count int = 0
		for {
			idata, isclosed := <-in_data
			if !isclosed {
				close(outdata)
				return
			}
			sdata := *idata
			if _, ok := pis.Logical_processing(sdata); ok {
				outdata <- idata
				down_count += pis.down_num
				continue
			}
			if down_count > 0 {
				outdata <- idata
				down_count--
			}
		}

	case "all":
		var down_count int = 0
		for {
			idata, isclosed := <-in_data
			if !isclosed {
				close(outdata)
				return
			}
			sdata := *idata

			if _, ok := pis.Logical_processing(sdata); ok {
				pis.Match_up(idata)
				r_list := pis.Match_extract()
				for _, r := range r_list {
					outdata <- r
				}
				down_count += pis.down_num
				continue
			}
			if down_count > 0 {
				outdata <- idata
				down_count--
			} else {
				pis.Match_up(idata)
			}

		}
	}
}

func (pis *Parameter_is) Logical_processing(s string) (string, bool) {
	or_status := true
	// 判断排除条件
	for _, ivalue := range pis.out_related_string {
		if symbol_judge(ivalue, s) {
			return "", false
		}
	}
	// 判断需要全部符合的条件
	for _, ivalue := range pis.in_related_string {
		if !symbol_judge(ivalue, s) {
			return "", false
		}
	}
	// 判断仅需要单独符合的条件
	for _, ivalue := range pis.or_related_string {
		or_status = false
		if symbol_judge(ivalue, s) {
			return "", true
		}
	}
	return "", or_status
}

func (ois Parameter_ois) Start_str(in_data chan *string, outdata chan *string) {
	// defer func() {
	// 	if r := recover(); r != nil {
	// 		fmt.Println("Parameter_ois Start_str error")
	// 	}
	// }()
	var k_num = 0
	var return_data = ""
	for {
		idata, isclosed := <-in_data
		if !isclosed {
			return_data = "字符: " + txt_mod(ois.one_in_string) + " 出现次数: " + strconv.Itoa(k_num)
			outdata <- &return_data
			close(outdata)
			return
		}
		sdata := *idata

		if _, ok := ois.Logical_processing(sdata); ok {
			k_num++
		}
	}
}

func (ois Parameter_ois) Logical_processing(s string) (string, bool) {
	if symbol_judge(ois.one_in_string, s) {
		return "", true
	}
	return "", false
}

func (pss Parameter_ss) Start_str(in_data chan *string, outdata chan *string) {
	// defer func() {
	// 	if r := recover(); r != nil {
	// 		fmt.Println("Parameter_ss Start_str error")
	// 	}
	// }()
	var num_data map[string]int
	var sum_data int
	var avg_data int
	var count int
	for {
		idata, isclosed := <-in_data
		if !isclosed {
			switch pss.split_type {
			case "num":
				j_data, err := json.Marshal(num_data)
				n_data := string(j_data)
				if err != nil {
					fmt.Println("格式化异常: ", err)
				} else {
					outdata <- &n_data
				}
			case "sum":
				n_data := "总和: " + strconv.Itoa(sum_data)
				outdata <- &n_data
			case "avg":
				avg_data = avg_data / count
				n_data := "平均值: " + strconv.Itoa(avg_data)
				outdata <- &n_data
			}
			close(outdata)
			return
		}
		sdata := *idata
		rdata, ok := pss.Logical_processing(sdata)
		if ok {
			switch pss.split_type {
			case "jane":
				// return_data := strings.Replace(strings.Trim(fmt.Sprint(rdata), "[]"), " ", " ", -1)
				outdata <- &rdata
				continue
			case "num":
				if _, ok = num_data[rdata]; ok {
					num_data[rdata]++
				} else {
					num_data[rdata] = 0
				}
			case "sum":
				return_data, err := strconv.Atoi(rdata)
				if err != nil {
					continue
				}
				sum_data += return_data
			case "avg":
				return_data, err := strconv.Atoi(rdata)
				if err != nil {
					continue
				}
				avg_data += return_data
				count++
			}
		}
	}

}

func (pss Parameter_ss) Logical_processing(s string) (string, bool) {
	r_list := []string{s}
	r_data := []string{}
	n_r_data := split_judge(r_list, pss.split_symbol_list, 0, r_data)
	if len(n_r_data) == 0 {
		return "", false
	}
	w_data, status := obtain_data(n_r_data, pss.split_location)
	return w_data, status
}

// 写入到缓存区，并从中排除超出范围的字符
func (pis *Parameter_is) Match_up(s *string) {
	pis.upward_list = append(pis.upward_list, s)
	if len(pis.upward_list) > pis.upward_num {
		pis.upward_list = pis.upward_list[1:]
	}
}

//读取缓存数据后并传入空串
func (pis *Parameter_is) Match_extract() []*string {
	m_list := pis.upward_list
	pis.upward_list = []*string{}
	return m_list
}

func (pzz *Parameter_zz) Init_judge() (bool, error) {
	var err error
	if pzz.regular_grammar != "none" {
		pzz.regular_Regexp, err = regexp.Compile(pzz.regular_grammar)
		if err != nil {
			return false, err
		}
		return true, nil
	} else {
		return false, nil
	}

}

func (pzz *Parameter_zz) Start_str(in_data chan *string, outdata chan *string) {
	switch pzz.regular_type {
	case "match":
		for {
			idata, isclosed := <-in_data
			if !isclosed {
				close(outdata)
				return
			}
			sdata := *idata
			if ok := pzz.match_processing(sdata); ok {
				outdata <- idata
			}
		}
	case "filter":
		for {
			idata, isclosed := <-in_data
			if !isclosed {
				close(outdata)
				return
			}
			sdata := *idata

			rdata := pzz.filter_processing(sdata)
			for _, r := range rdata {
				ndata := r + system_enter
				outdata <- &ndata
			}
		}
	}

}
func (pzz Parameter_zz) Logical_processing(s string) (string, bool) {
	return "", false
}

func (pzz Parameter_zz) match_processing(s string) bool {
	return pzz.regular_Regexp.MatchString(s)
}

func (pzz Parameter_zz) filter_processing(s string) []string {
	r := pzz.regular_Regexp.FindAllString(s, -1)
	return r
}

func (m mapstore) mapstart() {
	for _, v := range m {
		if v.read_status {
			go v.object.Start_str(read_store, one_store)
		} else {
			go v.object.Start_str(one_store, two_store)
		}
	}
}

func (m mapstore) Len() int {
	var l int
	for _ = range m {
		l++
	}
	return l
}
